Gomoku Source Code

MenuForm.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Client
{
public partial class MenuForm : Form
{
public MenuForm()
{
InitializeComponent();
}
private void singlePlayButton_Click(object sender, EventArgs e)
{
Hide();
SinglePlayForm singlePlayForm = new SinglePlayForm();
singlePlayForm.FormClosed += new FormClosedEventHandler(childForm_Closed);
singlePlayForm.Show();
}
private void exitButton_Click(object sender, EventArgs e)
{
System.Windows.Forms.Application.Exit();
}
void childForm_Closed(object sender, FormClosedEventArgs e)
{
Show();
}
private void multiPlayButton_Click(object sender, EventArgs e)
{
Hide();
MultiPlayForm multiPlayForm = new MultiPlayForm();
multiPlayForm.FormClosed += new FormClosedEventHandler(childForm_Closed);
multiPlayForm.Show();
}
}
}
MenuForm.Designer.cs
namespace Client
{
partial class MenuForm
{
/// <summary>
/// .
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// .
/// </summary>
/// <param name="disposing"> true, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form
/// <summary>
/// .
/// .
/// </summary>
private void InitializeComponent()
{
this.singlePlayButton = new System.Windows.Forms.Button();
this.exitButton = new System.Windows.Forms.Button();
this.multiPlayButton = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// singlePlayButton
//
this.singlePlayButton.Location = new System.Drawing.Point(245, 101);
this.singlePlayButton.Name = "singlePlayButton";
this.singlePlayButton.Size = new System.Drawing.Size(100, 40);
this.singlePlayButton.TabIndex = 0;
this.singlePlayButton.Text = "";
this.singlePlayButton.UseVisualStyleBackColor = true;
this.singlePlayButton.Click += new System.EventHandler(this.singlePlayButton_Click);
//
// exitButton
//
this.exitButton.Location = new System.Drawing.Point(245, 228);
this.exitButton.Name = "exitButton";
this.exitButton.Size = new System.Drawing.Size(100, 40);
this.exitButton.TabIndex = 1;
this.exitButton.Text = "";
this.exitButton.UseVisualStyleBackColor = true;
this.exitButton.Click += new System.EventHandler(this.exitButton_Click);
//
// multiPlayButton
//
this.multiPlayButton.Location = new System.Drawing.Point(245, 163);
this.multiPlayButton.Name = "multiPlayButton";
this.multiPlayButton.Size = new System.Drawing.Size(100, 40);
this.multiPlayButton.TabIndex = 2;
this.multiPlayButton.Text = "";
this.multiPlayButton.UseVisualStyleBackColor = true;
this.multiPlayButton.Click += new System.EventHandler(this.multiPlayButton_Click);
//
// MenuForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(584, 361);
this.Controls.Add(this.multiPlayButton);
this.Controls.Add(this.exitButton);
this.Controls.Add(this.singlePlayButton);
this.Name = "MenuForm";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button singlePlayButton;
private System.Windows.Forms.Button exitButton;
private System.Windows.Forms.Button multiPlayButton;
}
}
MultiPlayForm.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace Client
{
public partial class MultiPlayForm : Form
{
private Thread thread; //
private TcpClient tcpClient;// TCP
private NetworkStream stream;
private const int rectSize = 33; //
private const int edgeCount = 15; //
private enum Horse { none = 0, BLACK, WHITE };
private Horse[,] board;
private Horse nowPlayer;
private bool nowTurn;
private bool playing;
private bool entered;
private bool threading;
private bool judge(Horse Player) //
{
for (int i = 0; i < edgeCount - 4; i++) //
for (int j = 0; j < edgeCount; j++)
if (board[i, j] == Player && board[i + 1, j] == Player && board[i + 2, j] == Player &&
board[i + 3, j] == Player && board[i + 4, j] == Player)
return true;
for (int i = 0; i < edgeCount; i++) //
for (int j = 4; j < edgeCount; j++)
if (board[i, j] == Player && board[i, j - 1] == Player && board[i, j - 2] == Player &&
board[i, j - 3] == Player && board[i, j - 4] == Player)
return true;
for (int i = 0; i < edgeCount - 4; i++) // Y = X
for (int j = 0; j < edgeCount - 4; j++)
if (board[i, j] == Player && board[i + 1, j + 1] == Player && board[i + 2, j + 2] == Player &&
board[i + 3, j + 3] == Player && board[i + 4, j + 4] == Player)
return true;
for (int i = 4; i < edgeCount; i++) // Y = -X
for (int j = 0; j < edgeCount - 4; j++)
if (board[i, j] == Player && board[i - 1, j + 1] == Player && board[i - 2, j + 2] == Player &&
board[i - 3, j + 3] == Player && board[i - 4, j + 4] == Player)
return true;
return false;
}
private void refresh()
{
this.boardPicture.Refresh();
for (int i = 0; i < edgeCount; i++)
for (int j = 0; j < edgeCount; j++)
board[i, j] = Horse.none;
playButton.Enabled = false;
}
private void playButton_Click(object sender, EventArgs e)
{
if (!playing)
{
refresh();
playing = true;
string message = "[Play]";
byte[] buf = Encoding.ASCII.GetBytes(message + this.roomTextBox.Text);
stream.Write(buf, 0, buf.Length);
this.status.Text = " .";
this.playButton.Enabled = false;
}
}
public MultiPlayForm()
{
InitializeComponent();
this.playButton.Enabled = false;
playing = false;
entered = false;
threading = false;
board = new Horse[edgeCount, edgeCount];
nowTurn = false;
}
private void enterButton_Click(object sender, EventArgs e)
{
tcpClient = new TcpClient();
tcpClient.Connect("127.0.0.1", 9876);
stream = tcpClient.GetStream();
thread = new Thread(new ThreadStart(read));
thread.Start();
threading = true;
/* */
string message = "[Enter]";
byte[] buf = Encoding.ASCII.GetBytes(message + this.roomTextBox.Text);
stream.Write(buf, 0, buf.Length);
}
/* . */
private void read()
{
while (true)
{
byte[] buf = new byte[1024];
int bufBytes = stream.Read(buf, 0, buf.Length);
string message = Encoding.ASCII.GetString(buf, 0, bufBytes);
/* (: [Enter]) */
if (message.Contains("[Enter]"))
{
this.status.Text = "[" + this.roomTextBox.Text + "] .";
/* */
this.roomTextBox.Enabled = false;
this.enterButton.Enabled = false;
entered = true;
}
/* (: [Full]) */
if (message.Contains("[Full]"))
{
this.status.Text = " .";
closeNetwork();
}
/* (: [Play]{Horse}) */
if (message.Contains("[Play]"))
{
refresh();
string horse = message.Split(']')[1];
if (horse.Contains("Black"))
{
this.status.Text = " .";
nowTurn = true;
nowPlayer = Horse.BLACK;
}
else
{
this.status.Text = " .";
nowTurn = false;
nowPlayer = Horse.WHITE;
}
playing = true;
}
/* (: [Exit]) */
if (message.Contains("[Exit]"))
{
this.status.Text = " .";
refresh();
}
/* (: [Put]{X,Y}) */
if (message.Contains("[Put]"))
{
string position = message.Split(']')[1];
int x = Convert.ToInt32(position.Split(',')[0]);
int y = Convert.ToInt32(position.Split(',')[1]);
Horse enemyPlayer = Horse.none;
if (nowPlayer == Horse.BLACK)
{
enemyPlayer = Horse.WHITE;
}
else
{
enemyPlayer = Horse.BLACK;
}
if (board[x, y] != Horse.none) continue;
board[x, y] = enemyPlayer;
Graphics g = this.boardPicture.CreateGraphics();
if (enemyPlayer == Horse.BLACK)
{
SolidBrush brush = new SolidBrush(Color.Black);
g.FillEllipse(brush, x * rectSize, y * rectSize, rectSize, rectSize);
}
else
{
SolidBrush brush = new SolidBrush(Color.White);
g.FillEllipse(brush, x * rectSize, y * rectSize, rectSize, rectSize);
}
if (judge(enemyPlayer))
{
status.Text = ".";
playing = false;
playButton.Text = "";
playButton.Enabled = true;
}
else
{
status.Text = " .";
}
nowTurn = true;
}
}
}
private void boardPicture_MouseDown(object sender, MouseEventArgs e)
{
if (!playing)
{
MessageBox.Show(" .");
return;
}
if (!nowTurn)
{
return;
}
Graphics g = this.boardPicture.CreateGraphics();
int x = e.X / rectSize;
int y = e.Y / rectSize;
if (x < 0 || y < 0 || x >= edgeCount || y >= edgeCount)
{
MessageBox.Show(" .");
return;
}
if (board[x, y] != Horse.none) return;
board[x, y] = nowPlayer;
if (nowPlayer == Horse.BLACK)
{
SolidBrush brush = new SolidBrush(Color.Black);
g.FillEllipse(brush, x * rectSize, y * rectSize, rectSize, rectSize);
}
else
{
SolidBrush brush = new SolidBrush(Color.White);
g.FillEllipse(brush, x * rectSize, y * rectSize, rectSize, rectSize);
}
/* */
string message = "[Put]" + roomTextBox.Text + "," + x + "," + y;
byte[] buf = Encoding.ASCII.GetBytes(message);
stream.Write(buf, 0, buf.Length);
/* */
if (judge(nowPlayer))
{
status.Text = ".";
playing = false;
playButton.Text = "";
playButton.Enabled = true;
return;
}
else
{
status.Text = " .";
}
/* */
nowTurn = false;
}
private void boardPicture_Paint(object sender, PaintEventArgs e)
{
Graphics gp = e.Graphics;
Color lineColor = Color.Black; //
Pen p = new Pen(lineColor, 2);
gp.DrawLine(p, rectSize / 2, rectSize / 2, rectSize / 2, rectSize * edgeCount - rectSize / 2); //
gp.DrawLine(p, rectSize / 2, rectSize / 2, rectSize * edgeCount - rectSize / 2, rectSize / 2); //
gp.DrawLine(p, rectSize / 2, rectSize * edgeCount - rectSize / 2, rectSize * edgeCount - rectSize / 2, rectSize * edgeCount - rectSize / 2); //
gp.DrawLine(p, rectSize * edgeCount - rectSize / 2, rectSize / 2, rectSize * edgeCount - rectSize / 2, rectSize * edgeCount - rectSize / 2); //
p = new Pen(lineColor, 1);
//
for (int i = rectSize + rectSize / 2; i < rectSize * edgeCount - rectSize / 2; i += rectSize)
{
gp.DrawLine(p, rectSize / 2, i, rectSize * edgeCount - rectSize / 2, i);
gp.DrawLine(p, i, rectSize / 2, i, rectSize * edgeCount - rectSize / 2);
}
}
private void MultiPlayForm_FormClosed(object sender, FormClosedEventArgs e)
{
closeNetwork();
}
void closeNetwork()
{
if (threading && thread.IsAlive) thread.Abort();
if (entered)
{
tcpClient.Close();
}
}
}
}
MultiPlayForm.Designer.cs
namespace Client
{
partial class MenuForm
{
/// <summary>
/// .
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// .
/// </summary>
/// <param name="disposing"> true, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form
/// <summary>
/// .
/// .
/// </summary>
private void InitializeComponent()
{
this.singlePlayButton = new System.Windows.Forms.Button();
this.exitButton = new System.Windows.Forms.Button();
this.multiPlayButton = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// singlePlayButton
//
this.singlePlayButton.Location = new System.Drawing.Point(245, 101);
this.singlePlayButton.Name = "singlePlayButton";
this.singlePlayButton.Size = new System.Drawing.Size(100, 40);
this.singlePlayButton.TabIndex = 0;
this.singlePlayButton.Text = "";
this.singlePlayButton.UseVisualStyleBackColor = true;
this.singlePlayButton.Click += new System.EventHandler(this.singlePlayButton_Click);
//
// exitButton
//
this.exitButton.Location = new System.Drawing.Point(245, 228);
this.exitButton.Name = "exitButton";
this.exitButton.Size = new System.Drawing.Size(100, 40);
this.exitButton.TabIndex = 1;
this.exitButton.Text = "";
this.exitButton.UseVisualStyleBackColor = true;
this.exitButton.Click += new System.EventHandler(this.exitButton_Click);
//
// multiPlayButton
//
this.multiPlayButton.Location = new System.Drawing.Point(245, 163);
this.multiPlayButton.Name = "multiPlayButton";
this.multiPlayButton.Size = new System.Drawing.Size(100, 40);
this.multiPlayButton.TabIndex = 2;
this.multiPlayButton.Text = "";
this.multiPlayButton.UseVisualStyleBackColor = true;
this.multiPlayButton.Click += new System.EventHandler(this.multiPlayButton_Click);
//
// MenuForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(584, 361);
this.Controls.Add(this.multiPlayButton);
this.Controls.Add(this.exitButton);
this.Controls.Add(this.singlePlayButton);
this.Name = "MenuForm";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button singlePlayButton;
private System.Windows.Forms.Button exitButton;
private System.Windows.Forms.Button multiPlayButton;
}
}
main.cpp(Server)
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <Winsock.h>
#include <iostream>
#include <vector>
#include <sstream>
#pragma comment (lib, "ws2_32.lib")
using namespace std;
class Client {
private:
int clientID;
int roomID;
SOCKET clientSocket;
public:
Client(int clientID, SOCKET clientSocket) {
this->clientID = clientID;
this->roomID = -1;
this->clientSocket = clientSocket;
}
int getClientID() {
return clientID;
}
int getRoomID() {
return roomID;
}
void setRoomID(int roomID) {
this->roomID = roomID;
}
SOCKET getClientSocket() {
return clientSocket;
}
};
SOCKET serverSocket;
vector<Client> connections;
WSAData wsaData;
SOCKADDR_IN serverAddress;
int nextID;
vector<string> getTokens(string input, char delimiter) {
vector<string> tokens;
istringstream f(input);
string s;
while (getline(f, s, delimiter)) {
tokens.push_back(s);
}
return tokens;
}
int clientCountInRoom(int roomID) {
int count = 0;
for (int i = 0; i < connections.size(); i++) {
if (connections[i].getRoomID() == roomID) {
count++;
}
}
return count;
}
void playClient(int roomID) {
char* sent = new char[256];
bool black = true;
for (int i = 0; i < connections.size(); i++) {
if (connections[i].getRoomID() == roomID) {
ZeroMemory(sent, 256);
if (black) {
sprintf(sent, "%s", "[Play]Black");
black = false;
}
else {
sprintf(sent, "%s", "[Play]White");
}
send(connections[i].getClientSocket(), sent, 256, 0);
}
}
}
void exitClient(int roomID) {
char* sent = new char[256];
for (int i = 0; i < connections.size(); i++) {
if (connections[i].getRoomID() == roomID) {
ZeroMemory(sent, 256);
sprintf(sent, "%s", "[Exit]");
send(connections[i].getClientSocket(), sent, 256, 0);
}
}
}
void putClient(int roomID, int x, int y) {
char* sent = new char[256];
for (int i = 0; i < connections.size(); i++) {
if (connections[i].getRoomID() == roomID) {
ZeroMemory(sent, 256);
string data = "[Put]" + to_string(x) + "," + to_string(y);
sprintf(sent, "%s", data.c_str());
send(connections[i].getClientSocket(), sent, 256, 0);
}
}
}
void ServerThread(Client* client) {
char* sent = new char[256];
char* received = new char[256];
int size = 0;
while (true) {
ZeroMemory(received, 256);
if ((size = recv(client->getClientSocket(), received, 256, NULL)) > 0) {
string receivedString = string(received);
vector<string> tokens = getTokens(receivedString, ']');
if (receivedString.find("[Enter]") != -1) {
/* */
for (int i = 0; i < connections.size(); i++) {
string roomID = tokens[1];
int roomInt = atoi(roomID.c_str());
if (connections[i].getClientSocket() == client->getClientSocket()) {
int clientCount = clientCountInRoom(roomInt);
/* 2 */
if (clientCount >= 2) {
ZeroMemory(sent, 256);
sprintf(sent, "%s", "[Full]");
send(connections[i].getClientSocket(), sent, 256, 0);
break;
}
cout << " [" << client->getClientID() << "]: " << roomID << " " << endl;
/* */
Client* newClient = new Client(*client);
newClient->setRoomID(roomInt);
connections[i] = *newClient;
/* */
ZeroMemory(sent, 256);
sprintf(sent, "%s", "[Enter]");
send(connections[i].getClientSocket(), sent, 256, 0);
/* */
if (clientCount == 1) {
playClient(roomInt);
}
}
}
}
else if (receivedString.find("[Put]") != -1) {
/* */
string data = tokens[1];
vector<string> dataTokens = getTokens(data, ',');
int roomID = atoi(dataTokens[0].c_str());
int x = atoi(dataTokens[1].c_str());
int y = atoi(dataTokens[2].c_str());
/* */
putClient(roomID, x, y);
}
else if (receivedString.find("[Play]") != -1) {
/* */
string roomID = tokens[1];
int roomInt = atoi(roomID.c_str());
/* */
playClient(roomInt);
}
}
else {
ZeroMemory(sent, 256);
sprintf(sent, " [%i] .", client->getClientID());
cout << sent << endl;
/* */
for (int i = 0; i < connections.size(); i++) {
if (connections[i].getClientID() == client->getClientID()) {
/* */
if (connections[i].getRoomID() != -1 &&
clientCountInRoom(connections[i].getRoomID()) == 2) {
/* */
exitClient(connections[i].getRoomID());
}
connections.erase(connections.begin() + i);
break;
}
}
delete client;
break;
}
}
}
int main() {
WSAStartup(MAKEWORD(2, 2), &wsaData);
serverSocket = socket(AF_INET, SOCK_STREAM, NULL);
serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
serverAddress.sin_port = htons(9876);
serverAddress.sin_family = AF_INET;
cout << "[ C++ ]" << endl;
bind(serverSocket, (SOCKADDR*)&serverAddress, sizeof(serverAddress));
listen(serverSocket, 32);
int addressLength = sizeof(serverAddress);
while (true) {
SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, NULL);
if (clientSocket = accept(serverSocket, (SOCKADDR*)&serverAddress, &addressLength)) {
Client* client = new Client(nextID, clientSocket);
cout << "[ ]" << endl;
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ServerThread, (LPVOID)client, NULL, NULL);
connections.push_back(*client);
nextID++;
}
Sleep(100);
}
}